import os, re, webbrowser, yaml
from func import *
from guiapp import GuiApp
from urllib import parse
from tkinter import filedialog, messagebox

class MainWindow(GuiApp):
    def __init__(self, master=None):
        super().__init__(master)
        try:
            self.config = load_config(work_path + '\\config.yml')
        except:
            self.config = config_ini()
        self.combobox_ports['values'] = list(self.config['ports'].keys())
        self.port_name.set(value=self.config['port_name'])
        self.video_name.set(value=self.config['video_name'])
        self.threads.set(value=self.config['threads'])
        self.time_out.set(value=self.config['time_out'])
        self.n_digit.set(value=self.config['n_digit'])
        self.n_start.set(value=self.config['n_start'])
        self.ff_address.set(value=self.config['ff_address'])
        self.FFmpeg.set(value=self.config['FFmpeg'])
        
        self.button_play.configure(command=self.__play_callback)
        self.button_select.configure(command=self.__select_callback)
        self.button_download.configure(command=self.__download_callback)
        self.button_open.configure(command=self.__open_callback)

    def __play_callback(self):
        port = self.config['ports'][self.port_name.get()]
        if re.match(r'^https?://\w.+$', self.url.get()):
            ip = parse.quote_plus(self.url.get())
            webbrowser.open(port + ip)
        else:
            messagebox.showerror(title='Error', message='Invalid Address!')
            
    def __select_callback(self):
        file = filedialog.askopenfilename(title='Select m3u8 file', filetypes=(('m3u8','*.m3u8'),))
        if file:
            self.video_name.set(os.path.splitext(os.path.split(file)[1])[0])
            self.address.set(file)

    def __download_callback(self):
        self.button_download.configure(state='disable')
        try:
            down_path = filedialog.askdirectory(title='Select folder to download')
            os.chdir(down_path)
            video_name = self.video_name.get()
            address = self.address.get()
            threads = self.threads.get()
            time_out = self.time_out.get()
            n_digit = self.n_digit.get()
            n_start = self.n_start.get()
            ff_address = self.ff_address.get()
            
            if os.path.splitext(address)[1] == '.ts':
                urls = analyze_segment(address, n_digit, n_start, time_out)
                cryptor = None
            else:
                urls, cryptor = analyze_m3u8(address)   
            
            if os.path.exists(video_name):
                creat_new = messagebox.askyesno(title='Folder Exists', message='"%s" already exists, CREAT a NEW ONE?'%video_name, default=messagebox.NO)
                if creat_new:
                    while os.path.exists(video_name):
                        video_name += '(1)'
                    os.mkdir(video_name)
            else:
                os.mkdir(video_name)
            
            list_na = index_na(video_name, range(len(urls)))
            print('Start downloading (total %s):'%(len(urls)))    
            if list_na:
                list_index_download(video_name, urls, list_na, threads, cryptor, time_out)
                list_na = index_na(video_name, range(len(urls)))
                if list_na:
                    print('%s not downloaded.'%list_na)
            print('Checking incomplete items:')
            list_0 = check_0(video_name)
            if list_0:
                list_index_download(video_name, urls, list_0, threads, cryptor, time_out)
                list_0 = check_0(video_name)
                if list_0:
                    print('%s not complete.'%list_0)
            print('({}/{}) segments downloaded.'.format(len(os.listdir(video_name)), len(urls)))
            print('Merging video:')
            
            if self.FFmpeg.get():
                try:
                    FFmpeg_merge(video_name, ff_exe=ff_address)
                except Exception as e:
                    print(e)
                    print('Merging without FFmpeg ...')
                    merge(video_name)
            else:
                merge(video_name)
        
        except Exception as e:
            messagebox.showerror(title='Error', message=e)
        
        finally:
            self.button_download.configure(state='normal')
        
    def __open_callback(self):
        os.startfile(os.getcwd())

    def save_config(self):
        self.config['FFmpeg'] = self.FFmpeg.get()
        self.config['ff_address'] = self.ff_address.get()
        self.config['n_digit'] = self.n_digit.get()
        self.config['n_start'] = self.n_start.get()
        self.config['port_name'] = self.port_name.get()
        self.config['threads'] = self.threads.get()
        self.config['time_out'] = self.time_out.get()
        with open(work_path + '\\config.yml', 'w', encoding='utf-8') as f:
            yaml.dump(self.config, f, allow_unicode=True)

if __name__ == '__main__':
    app = MainWindow()
    app.run()
    app.save_config()